/**
 * @file adc.c
 * @author ait_zhengchunyu (ait_zhengchunyu@163.com)
 * @brief  adc 相关抽象层
 * @version 0.1
 * @date 2022-02-09
 * 
 * @copyright Copyright (c) 2022
 * 
 */
#include "adc.h"
#include "../dbg/dbg.h"
#include <math.h>
double e_param ;
#define TESTADC 0
static struct adc_dev_t adc_device;
static uint16_t adcFilterCount = 0;//adc滤波循环计数
static uint32_t filterSum[ADC_MAX_NUM];//滤波计算和
    

/**
 * @brief 滤波函数
 * 
 */
static int adc_filter(struct adc_dev_t *dev)
{
		uint16_t i;
    for(i=0;i<ADC_MAX_NUM;i++)
		{
        filterSum[i] += dev->read_hal_adc(i);
    }
    adcFilterCount++;
    if(adcFilterCount==ADC_FILTER_MAX)
    {
        adcFilterCount = 0;
				for(i=0;i<ADC_MAX_NUM;i++)
				{	
					dev->fact_vol[i] = filterSum[i]/ADC_FILTER_MAX;
					filterSum[i] = 0;
				}
    }
    return 0;
}

/**
 * @brief adc 转换函数
 * 
 */
//X=1177692.5/(3950+(log((V/vin-1)/loge)*298.15-273.15 ,

//其中X是最终检测到的实际温度，
//V是单片机供电电压，=3.5v			
//VIN是温度口的采样电压，ln是数学公式
double lg_n,lg_e,lg_vin,lg_vpower ,log_v;
float a_temp_parm ;
float vdd_power = 3.3;//供电电压值
uint8_t stepcount = 0;
static void get_temp_step(struct adc_dev_t *dev,uint8_t stepval)
{
	switch(stepval)
	{
		case 0:
			e_param = exp(1.0);
		break;
		case 1:
			lg_vpower =(vdd_power/32767)*(dev->fact_vol[0]);//实际采集的电压值
		break;
		case 2:
			lg_vpower = lg_vpower*1.0822;
			if(lg_vpower==0)
			{
				stepval = 0;
			}
	  break;
		case 3:
			lg_vin= vdd_power/(lg_vpower)-1;
		break;
		case 4:
			lg_e = log(e_param);
		break;
		case 5:
			lg_n = log(lg_vin);
		break;
		case 6:
			log_v = lg_n/lg_e;
		break;
		case 7:
			log_v = log_v*298.15;
		break;
		case 8:
			 log_v = 3950+log_v;
		break;
		case 9:
				log_v =1177692.5/log_v;
		break;
		case 10:
			dev->show_vol[0] =log_v-273.15 ;
		break;
	}
}



static int adc_convert_func(struct adc_dev_t *dev)
{
    int i;
    float Utmp ,U1tmp ,Usettings,Usample,Umax_dis_value; 
    adc_filter(dev);
    for ( i = 0; i < ADC_MAX_NUM; i++)
    {
       //dev->fact_vol[i] = dev->read_hal_adc(i);

      if(dev->factor[i].in_setting<1)dev->factor[i].in_setting=1;
      if(dev->factor[i].in_sample<1)dev->factor[i].in_sample=1;
      if(dev->factor[i].max_dis_value<1)dev->factor[i].max_dis_value =1;
#if TESTADC
         dev->show_vol[i] =479.25;
#else
      if(i!=0)
      {
        
            /**
             * 最终显示电压 = (实际采样电压值*外部输入电压值*4096)/(外部输入电压情况下采样份数*1024*更改最大基准对应的最高显示电压)
             */
/*
				Utmp = (dev->factor[i].in_sample*dev->factor[i].max_dis_value)/32767;
				U1tmp=(dev->fact_vol[i]*dev->factor[i].max_dis_value)/32767;
				dev->show_vol[i] = (U1tmp*dev->factor[i].in_setting)/Utmp;
*/
        //dev->show_vol[i] = (dev->fact_vol[i]*dev->factor[i].in_setting*4096)/(dev->factor[i].in_sample*1024*dev->factor[i].max_dis_value);
				//dev->factor[i].max_dis_value //在实际计算中缩小10倍 /10
                //dev->factor[i].in_setting 在实际计算中缩小10倍 /10
				Usettings = dev->factor[i].in_setting;
				Usample =dev->factor[i].in_sample;
				Umax_dis_value =dev->factor[i].max_dis_value;
				Utmp = (Usample*Umax_dis_value)/327670;
				U1tmp=(dev->fact_vol[i]*Umax_dis_value)/327670;
				dev->show_vol[i] = (U1tmp*Usettings)/(Utmp*10);
      }
      else
      {
   			stepcount++;
				if(stepcount>10)stepcount = 0;
				 get_temp_step(dev,stepcount);
      }
#endif 


    }
    dev->comple_flag=1;//转换完成
    return 0;

}

/**
 * @brief adc 转换完成函数 1 转换完成 0 未转换完成
 * 
 */
static uint8_t adc_convert_to_complete(struct adc_dev_t *dev)
{
    if(dev->convert_func(dev)!=0)
    return 0xff;
    if(dev->comple_flag==1)
    {
        dev->comple_flag=0;
        return 1;
    }
    return 0;
}
/**
 * @brief 获取实际adc值
 * 
 */
static uint16_t adc_get_voltage(struct adc_dev_t *dev,uint8_t num)
{

    return (uint16_t )*(dev->fact_vol+num);


}
/**
 * @brief 获取比例后的adc值
 * 
 */
static float adc_get_factor_voltage(struct adc_dev_t *dev,uint8_t num)
{

    return (float )*(dev->show_vol+num);

}

/**
 * @brief 设置放大倍数
 * 
 */
static int adc_set_factor(struct adc_dev_t *dev,uint8_t num,struct vol_fator_t *param)
{
    if(dev==NULL) return -1;
    if(num>ADC_MAX_NUM) return -2;
    //dev->factor[num] = val;
    dev->factor[num].in_setting     = param->in_setting     ;//输入设定值
    dev->factor[num].in_sample      = param->in_sample      ;//输入采样值
    dev->factor[num].max_dis_value  = param->max_dis_value  ;//最高显示电压 
    return 0;
}
/**
 * @brief 获取放大倍数
 * 
 */
static int adc_get_factor(struct adc_dev_t *dev,uint8_t num,struct vol_fator_t **param)
{
    if(dev==NULL) return -1;
    if(num>ADC_MAX_NUM) return -2;
    *param= &(dev->factor[num]);
    return 0;
}
static void adc_init_factor(void)
{
    int i;
    for ( i = 0; i < ADC_MAX_NUM; i++)
    {
        adc_device.factor[i].in_setting     = 400;
        adc_device.factor[i].in_sample      = 400;
        adc_device.factor[i].max_dis_value  = ADC_MAX_DIS;
    }
}
int adc_init(struct adc_dev_t **dev)
{

    adc_hal_init();
    adc_init_factor();
    adc_device.num = ADC_MAX_NUM; //adc number
    adc_device.comple_flag = 0;// 转换完成标志
    /**
     * @brief read_hal_adc ,convert_update 需要底层提供
     * 
     */
    adc_device.read_hal_adc             =   adc_hal_get_value;
    adc_device.convert_update           =   adc_loop_update;
    adc_device.convert_func             =   adc_convert_func;
    adc_device.convert_to_complete      =   adc_convert_to_complete;
    adc_device.convert_func             =   adc_convert_func;
    adc_device.get_voltage              =   adc_get_voltage;
    adc_device.get_factor_voltage       =   adc_get_factor_voltage;
    adc_device.filter                   =   adc_filter  ;
    adc_device.set_factor               =   adc_set_factor;
    adc_device.get_factor               =   adc_get_factor;

    *dev = &adc_device;
		return 0;

}

